package com.ybkj.daijia.server.controller;

import com.ybkj.daijia.Setting;
import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.common.MediaUtil;
import com.ybkj.daijia.common.Pager;
import com.ybkj.daijia.common.Principal;
import com.ybkj.daijia.common.Result;
import com.ybkj.daijia.server.exception.NoPermissionException;
import com.ybkj.daijia.page.Page;
import com.ybkj.daijia.server.event.model.OperationLogEvent;
import com.ybkj.daijia.server.model.Company;
import com.ybkj.daijia.server.news.NoticeNews;
import com.ybkj.daijia.server.service.CompanyService;
import com.ybkj.daijia.server.service.NewsService;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.util.WebUtils;

@Controller
@RequestMapping(value = "news")
public class NewsController {

    @Autowired
    private SettingUtils settingUtils;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private NewsService newsService;

    @Autowired
    private CompanyService companyService;

    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;


    /**
     * 跳转新闻列表
     *
     * @return
     */
    @RequestMapping(value = "list", method = RequestMethod.GET)
    public ModelAndView list() {
        Subject subject = SecurityUtils.getSubject();
        if (!subject.isPermitted("news")) { // 没有权限
            throw new NoPermissionException();
        }
        ModelAndView mv = new ModelAndView();

        // 获取公司类型，如果是主公司，则获取其分公司，便于主公司查询其分公司的广告
        Principal principal = (Principal) subject.getPrincipal();
        boolean isMain = principal.isCompanyType();
        if (isMain) {
            List<Company> companys = companyService.findAll();
            Long mainId = principal.getCompanyId();
            String mainName = principal.getCompanyName();
            mv.addObject("companys", companys);
            mv.addObject("mainId", mainId);
            mv.addObject("mainName", mainName);
        }
        mv.addObject("appKey", settingUtils.get().getSecKey());
        mv.setViewName("news/list");
        return mv;
    }

    /**
     * 跳转添加页面
     *
     * @return
     */
    @ResponseBody
    @RequestMapping("add")
    public ModelAndView add() {
        Subject subject = SecurityUtils.getSubject();
        if (subject.isPermitted("news")) {
            ModelAndView mv = new ModelAndView();
            Principal principal = (Principal) subject.getPrincipal();
            // 获取公司，如果是主公司，则可以为分公司添加，也包括自己，如果是子公司，则谁登陆就是为谁添加
            boolean isMain = principal.isCompanyType(); // 是不是主公司
            if (isMain) {
                List<Company> companys = companyService.findAll(); // 获取该主公司的所有分公司，包括自己
                mv.addObject("companys", companys);
            }
            mv.addObject("appKey", settingUtils.get().getSecKey());
            mv.addObject("author", principal.getUsername());
            mv.setViewName("news/add");
            return mv;
        } else {
            throw new NoPermissionException();
        }
    }

    /**
     * 添加新闻
     *
     * @param status      状态
     * @param title       标题
     * @param author      作者
     * @param image       图片地址
     * @param content     内容
     * @param serviceType 服务类型
     * @param contType    移动终端类型
     * @param companyId   公司ID，是主公司时需要传入
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "createNews", method = RequestMethod.POST)
    public Result<NoticeNews> create(
        int status,
        String serviceType,
        String contType,
        String link,
        String content,
        MultipartFile image,
        String author,
        String title,
        String created,
        Long companyId) throws Exception {

        Result<NoticeNews> result = new Result<NoticeNews>();
        Setting setting = settingUtils.get();

        String fileName = image.getOriginalFilename();

        if (MediaUtil.isPicture(image, "")) {

            fileName = String.valueOf(System.currentTimeMillis() / 1000) + fileName;

            String realpath = WebUtils.getRealPath(request.getSession().getServletContext(), "/");

            File targetFile = new File(realpath + "/upload/news/", fileName);
            if (!targetFile.exists()) {
                targetFile.getParentFile().mkdirs();
                targetFile.createNewFile();
            }
            Files.write(Paths.get(targetFile.getPath()), image.getBytes());
        } else {
            result.setSuccess(false);
            result.setMessage("只能上传图片");
            return result;
        }

        // 只能选填链接或者内容
        if ((null == link || link.isEmpty())
            && (null == content || content.isEmpty())) {
            result.setSuccess(false);
            result.setMessage("请您为您的广告添加链接或者编写内容，必须有且只能有一个，[内容/链接二选一]");
            return result;
        }
        if (null != link
            && !link.isEmpty()
            && null != content
            && !content.isEmpty()) {
            result.setSuccess(false);
            result.setMessage("广告链接和广告内容只能选填一个");
            return result;
        }

        Subject subject = SecurityUtils.getSubject();
        Principal principal = (Principal) subject.getPrincipal();
        if (subject.isPermitted("news")) {
//			if(!webUrl.equals(referer)){
//				result.setMessage("禁止CRSF攻击");
//				return result;
//			}
            NoticeNews noticeNews = new NoticeNews();
            // 获取公司，如果是主公司，则可以为分公司添加，也包括自己，如果是子公司，则谁登陆就是为谁添加
            boolean isMain = principal.isCompanyType(); // 是不是主公司
            if (!isMain) {
                // 不是主公司，谁登陆给谁添加
                companyId = principal.getCompanyId(); // 获取公司Id
            }
            noticeNews.setCompanyId(companyId);
            noticeNews.setAuthor(author);
            noticeNews.setContent(content);
            noticeNews.setContType(contType);
            noticeNews.setImage("/upload/news/" + fileName);
            noticeNews.setLink(link);
            noticeNews.setServiceType(serviceType);
            noticeNews.setStatus(status);
            noticeNews.setTitle(title);
            noticeNews.setCreated(System.currentTimeMillis());
            result = newsService.create(noticeNews);

            if (result.isSuccess()) {
                System.out.println("增加新闻成功");
                String detail = "【%s】新增了新闻【" + noticeNews.getTitle() + "】";
                OperationLogEvent operationLogEvent = new OperationLogEvent(principal, detail);
                applicationEventMulticaster.multicastEvent(operationLogEvent);
            }
            return result;

        } else {
            result.setSuccess(false);
            result.setMessage("您没有该权限");
            return result;
        }
    }

    /**
     * 更新新闻
     *
     * @param id      新闻ID
     * @param status  新闻状态
     * @param title
     * @param author
     * @param created
     * @param image
     * @param content
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "updateNews", method = RequestMethod.POST)
    public Result<NoticeNews> updateNews(
        Long id,
        int status,
        String serviceType,
        String contType,
        String link,
        String content,
        MultipartFile image,
        String author,
        String title,
        String created,
        Long companyId) throws Exception {

        Result<NoticeNews> result = new Result<NoticeNews>();

        String fileName = image.getOriginalFilename();

        if (MediaUtil.isPicture(image, "")) {

            fileName = String.valueOf(System.currentTimeMillis() / 1000) + fileName;

            String realpath = WebUtils.getRealPath(request.getSession().getServletContext(), "/");

            File targetFile = new File(realpath + "/upload/news/", fileName);
            if (!targetFile.exists()) {
                targetFile.getParentFile().mkdirs();
                targetFile.createNewFile();
            }
            Files.write(Paths.get(targetFile.getPath()), image.getBytes());
        } else {
            result.setSuccess(false);
            result.setMessage("只能上传图片");
            return result;
        }

        // 只能选填链接或者内容
        if ((null == link || link.isEmpty())
            && (null == content || content.isEmpty())) {
            result.setSuccess(false);
            result.setMessage("请您为您的广告添加链接或者编写内容，必须有且只能有一个，[内容/链接二选一]");
            return result;
        }
        if (null != link
            && !link.isEmpty()
            && null != content
            && !content.isEmpty()) {
            result.setSuccess(false);
            result.setMessage("广告链接和广告内容只能选填一个");
            return result;
        }

        Subject subject = SecurityUtils.getSubject();
        Principal principal = (Principal) subject.getPrincipal();

        if (subject.isPermitted("news")) {

            NoticeNews noticeNews = new NoticeNews();
            noticeNews.setId(id);
            noticeNews.setAuthor(author);
            noticeNews.setContent(content);
            noticeNews.setContType(contType);
            noticeNews.setImage("/upload/news/" + fileName);
            noticeNews.setLink(link);
            noticeNews.setServiceType(serviceType);
            noticeNews.setStatus(status);
            noticeNews.setTitle(title);
            noticeNews.setCompanyId(companyId);
            noticeNews.setCreated(System.currentTimeMillis());
            result = newsService.update(noticeNews);

            if (result.isSuccess()) {
                String detail = "【%s】修改了新闻【" + noticeNews.getTitle() + "】";
                OperationLogEvent operationLogEvent = new OperationLogEvent(principal, detail);
                applicationEventMulticaster.multicastEvent(operationLogEvent);
            }
            return result;

        } else {
            result.setSuccess(false);
            result.setMessage("您没有该权限");
            return result;
        }

    }

    /**
     * 删除新闻
     *
     * @param id
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "deleteNews", method = RequestMethod.GET)
    public Result<NoticeNews> deleteNews(Long id) {

        Subject subject = SecurityUtils.getSubject();
        Result<NoticeNews> result = new Result<>();

        if (subject.isPermitted("news")) {
            result = newsService.delete(id);
            return result;

        } else {
            result.setSuccess(false);
            result.setMessage("您没有该权限");
            return result;
        }

    }

    /**
     * 置顶新闻
     */
    @ResponseBody
    @RequestMapping(value = "topNews", method = RequestMethod.GET)
    public Result<NoticeNews> topNews(NoticeNews noticeNews) {

        Subject subject = SecurityUtils.getSubject();
        Result<NoticeNews> result = new Result<>();

        if (subject.isPermitted("news")) {
            noticeNews.setStatus(2);
            result = newsService.update(noticeNews);
            return result;

        } else {
            result.setSuccess(false);
            result.setMessage("您没有该权限");
            return result;
        }

    }

    /**
     * 获取指定系统的指定服务和移动类型终端的广告列表
     *
     * @param serviceType 服务类型
     * @param contType    移动端类型
     * @param page        页码
     * @param rows        行
     * @return
     */
    @ResponseBody
    @RequestMapping("listData")
    public Page<Map<String, Object>> listData(
        @RequestParam(required = false, value = "serviceType") String serviceType,
        @RequestParam(required = false, value = "contType") String contType,
        @RequestParam(required = false, value = "companyId") Long companyId,
        @RequestParam(required = false, value = "page") Integer page,
        @RequestParam(required = false, value = "rows") Integer rows) {
        Subject subject = SecurityUtils.getSubject();
        if (subject.isPermitted("news")) {
            page = Pager.getPage();
            rows = Pager.getLimit();
            Page<Map<String, Object>> pager = null;

            // companyId不为空，查出需要查询的公司的信息
            if (null != companyId) {
                return pager = newsService
                    .queryNews(null, companyId, serviceType, contType, page, rows);
            }

            // companyId为空，获取公司类型，如果是主公司，获取所属公司的所有广告
            Principal principal = (Principal) subject.getPrincipal();
            boolean isMain = principal.isCompanyType(); // 是不是主公司
            if (isMain) { // 获取该主公司的所有分公司，包括自己
                List<Company> companys = companyService.findAll();
                StringBuffer buffer = new StringBuffer();
                for (int i = 0; i < companys.size(); i++) {
                    if (i == companys.size() - 1) {
                        buffer.append(String.valueOf(companys.get(i).getId()));
                    } else {
                        buffer.append(String.valueOf(companys.get(i).getId())).append(",");
                    }
                }
                String companyIds = buffer.toString();
                pager = newsService
                    .queryNews(companyIds, companyId, serviceType, contType, page, rows);
            } else {
                companyId = principal.getCompanyId();
                pager = newsService.queryNews(null, companyId, serviceType, contType, page, rows);
            }

            return pager;
        } else {
            throw new NoPermissionException();
        }
    }

    /**
     * 跳转编辑界面
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "detail/{id}", method = RequestMethod.GET)
    public ModelAndView detail(@PathVariable("id") Long id) {

        ModelAndView mv = new ModelAndView();
        Subject subject = SecurityUtils.getSubject();

        if (subject.isPermitted("news")) {
            NoticeNews noticeNews = newsService.findOne(id);
            // 获取公司，如果是主公司，则可以为分公司添加，也包括自己，如果是子公司，则谁登陆就是为谁添加
            Principal principal = (Principal) subject.getPrincipal();
            boolean isMain = principal.isCompanyType(); // 是不是主公司
            if (isMain) {
                List<Company> companys = companyService.findAll(); // 获取该主公司的所有分公司，包括自己
                mv.addObject("companys", companys);
            }
            mv.addObject("noticeNews", noticeNews);
            mv.addObject("created",
                com.ybkj.daijia.constant.DateConstant.DATE_TIME.format(noticeNews.getCreated() * 1000));
            mv.setViewName("news/edit");
            return mv;

        } else {
            throw new NoPermissionException();
        }
    }

    /**
     * 查看单个新闻
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "look/{id}", method = RequestMethod.GET)
    public ModelAndView look(@PathVariable("id") Long id) {
        ModelAndView mv = new ModelAndView();
        Subject subject = SecurityUtils.getSubject();

        if (subject.isPermitted("news")) {
            NoticeNews noticeNews = newsService.findOne(id);
            mv.addObject("noticeNews", noticeNews);
            Company company = companyService.findOne(noticeNews.getCompanyId());
            mv.addObject("companyName", company.getCompanyName());
            mv.addObject("created",
                com.ybkj.daijia.constant.DateConstant.DATE_TIME.format(noticeNews.getCreated() * 1000));
            mv.setViewName("news/detail");
            return mv;

        } else {
            throw new NoPermissionException();
        }
    }

    @org.springframework.web.bind.annotation.InitBinder
    public void InitBinder(WebDataBinder dataBinder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        dateFormat.setLenient(false);
        dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
    }

}
